#pragma once
#include<iostream>

#include<functional>
#include"Protocol.hpp"
#include"Socket.hpp"
#include"InetAddr.hpp"
#include"Log.hpp"
#include"LockGuard.hpp"
//using service_io_t = std::function<void(SockSPtr, const InetAddr&)
using namespace socket_ns;
using namespace log_ns;

using process_t = std::function<std::shared_ptr<Response>(std::shared_ptr<Request>)>;

class IOService
{
public:
    IOService(process_t process)
        :_process(process)
    {}
    void IOExcute(SockSPtr sock, InetAddr &addr) 
    {
        std::string packagestreamqueue;
        while(true)
        {
            // std::string message;
            //1.负责读取
            ssize_t n = sock->Recv(&packagestreamqueue);
            if(n <= 0)
            {
                // LOG(INFO, "get message from client %s, message : %s\n", addr.AddrStr().c_str(), message.c_str());
                // std::string hello = "hello";

                // sock->Send(hello);
                LOG(INFO, "client %s quit or recv error \n", addr.AddrStr().c_str());
                break;
            }
            //2.报文解析
            // 不能保证读到完整报文
            std::string package = Decode(packagestreamqueue);
            if(package.empty()) continue;
            //能保证了
            auto req = Factory::BuildRequestDefault();

            //3.反序列化
            req->Deserialize(package);

            //4.业务处理
            auto resp = _process(req); //通过请求 得到应答

            //5.序列化应答
            std::string respjson;
            resp->Serialize(&respjson);

            //6.添加应答
            respjson = Encode(respjson);
            //7.发送回去
            sock->Send(respjson);
        }
    }
    ~IOService()
    {}
private:
    process_t _process;
};